home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / demos / reflect.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-29  |  8.2 KB  |  384 lines

  1. /* reflect.c */
  2.  
  3. /*
  4.  * Demo of a reflective, texture-mapped surface with OpenGL.
  5.  * Brian Paul  (brianp@ssec.wisc.edu)  August 14, 1995
  6.  *
  7.  * Hardware texture mapping is highly recommended!
  8.  *
  9.  * The basic steps are:
  10.  *    1. Render the reflective object (a polygon) from the normal viewpoint,
  11.  *       setting the stencil planes = 1.
  12.  *    2. Render the scene from a special viewpoint:  the viewpoint which
  13.  *       is on the opposite side of the reflective plane.  Only draw where
  14.  *       stencil = 1.  This draws the objects in the reflective surface.
  15.  *    3. Render the scene from the original viewpoint.  This draws the
  16.  *       objects in the normal fashion.  Use blending when drawing
  17.  *       the reflective, textured surface.
  18.  *
  19.  * This is a very crude demo.  It could be much better.
  20.  */
  21.  
  22. /*
  23.  * Dirk Reiners (reiners@igd.fhg.de) made some modifications to this code.
  24.  *
  25.  * August 1996 - A few optimizations by Brian
  26.  */
  27.  
  28.  
  29.  
  30. #define USE_ZBUFFER
  31.  
  32.  
  33. /* OK, without hardware support this is overkill. */
  34. #define USE_TEXTURE
  35.  
  36. #include <math.h>
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include "gltk.h"
  40.  
  41.  
  42. #define DEG2RAD (3.14159/180.0)
  43.  
  44.  
  45. #define TABLE_TEXTURE "../samples/1.rgb"
  46.  
  47.  
  48. #define MAX_OBJECTS 2
  49.  
  50. static GLint table_list;
  51. static GLint objects_list[MAX_OBJECTS];
  52.  
  53.  
  54. static GLfloat xrot, yrot;
  55. static GLfloat spin;
  56.  
  57.  
  58.  
  59. static void make_table( void )
  60. {
  61.    static GLfloat table_mat[] = { 1.0, 1.0, 1.0, 0.6 };
  62.    static GLfloat gray[] = { 0.4, 0.4, 0.4, 1.0 };
  63.  
  64.    table_list = glGenLists(1);
  65.    glNewList( table_list, GL_COMPILE );
  66.  
  67.    /* load table's texture */
  68.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, table_mat );
  69. /*   glMaterialfv( GL_FRONT, GL_EMISSION, gray );*/
  70.    glMaterialfv( GL_FRONT, GL_DIFFUSE, table_mat );
  71.    glMaterialfv( GL_FRONT, GL_AMBIENT, gray );
  72.    
  73.    /* draw textured square for the table */
  74.    glPushMatrix();
  75.    glScalef( 4.0, 4.0, 4.0 );
  76.    glBegin( GL_POLYGON );
  77.    glNormal3f( 0.0, 1.0, 0.0 );
  78.    glTexCoord2f( 0.0, 0.0 );   glVertex3f( -1.0, 0.0,  1.0 );
  79.    glTexCoord2f( 1.0, 0.0 );   glVertex3f(  1.0, 0.0,  1.0 );
  80.    glTexCoord2f( 1.0, 1.0 );   glVertex3f(  1.0, 0.0, -1.0 );
  81.    glTexCoord2f( 0.0, 1.0 );   glVertex3f( -1.0, 0.0, -1.0 );
  82.    glEnd();
  83.    glPopMatrix();
  84.  
  85.    glDisable( GL_TEXTURE_2D );
  86.  
  87.    glEndList();
  88. }
  89.  
  90.  
  91. static void make_objects( void )
  92. {
  93.    GLUquadricObj *q;
  94.  
  95.    static GLfloat cyan[] = { 0.0, 1.0, 1.0, 1.0 };
  96.    static GLfloat green[] = { 0.2, 1.0, 0.2, 1.0 };
  97.    static GLfloat black[] = { 0.0, 0.0, 0.0, 0.0 };
  98.  
  99.    q = gluNewQuadric();
  100.    gluQuadricDrawStyle( q, GLU_FILL );
  101.    gluQuadricNormals( q, GLU_SMOOTH );
  102.  
  103.    objects_list[0] = glGenLists(1);
  104.    glNewList( objects_list[0], GL_COMPILE );
  105.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cyan );
  106.    glMaterialfv( GL_FRONT, GL_EMISSION, black );
  107.    gluCylinder( q, 0.5, 0.5,  1.0, 15, 10 );
  108.    glEndList();
  109.  
  110.    objects_list[1] = glGenLists(1);
  111.    glNewList( objects_list[1], GL_COMPILE );
  112.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green );
  113.    glMaterialfv( GL_FRONT, GL_EMISSION, black );
  114.    gluCylinder( q, 1.5, 0.0,  2.5, 15, 10 );
  115.    glEndList();
  116. }
  117.  
  118.  
  119.  
  120. static void init( void )
  121. {
  122.    static GLfloat light_pos[] = { 0.0, 0.0, 20.0, 1.0 };
  123.    TK_RGBImageRec *image;
  124.  
  125.    make_table();
  126.    make_objects();
  127.  
  128.    /* Setup texture */
  129. #ifdef USE_TEXTURE
  130.    image = tkRGBImageLoad( TABLE_TEXTURE );
  131.    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image->sizeX, image->sizeY,
  132.                      GL_RGB, GL_UNSIGNED_BYTE, image->data);
  133.  
  134.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
  135.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
  136.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  137.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  138. #endif
  139.  
  140.  
  141.    xrot = 30.0;
  142.    yrot = 50.0;
  143.    spin = 0.0;
  144.  
  145. #ifndef USE_ZBUFFER
  146.    glEnable( GL_CULL_FACE );
  147. #endif
  148.  
  149.    glShadeModel( GL_FLAT );
  150.    
  151.    glEnable( GL_LIGHT0 );
  152.    glEnable( GL_LIGHTING );
  153.  
  154.    glLightfv( GL_LIGHT0, GL_POSITION, light_pos );
  155.  
  156.    glClearColor( 0.5, 0.5, 0.5, 1.0 );
  157.  
  158.    glEnable( GL_NORMALIZE );
  159. }
  160.  
  161.  
  162.  
  163. static void reshape(int w, int h)
  164. {
  165.    GLfloat aspect = (float) w / (float) h;
  166.  
  167.    glViewport(0, 0, w, h);
  168.    glMatrixMode(GL_PROJECTION);
  169.    glLoadIdentity();
  170.    glFrustum( -aspect, aspect, -1.0, 1.0, 4.0, 300.0 );
  171.    glMatrixMode(GL_MODELVIEW);
  172.    glLoadIdentity();
  173. }
  174.  
  175.  
  176.  
  177. static void draw_objects( GLfloat eyex, GLfloat eyey, GLfloat eyez )
  178. {
  179. #ifndef USE_ZBUFFER
  180.     if (eyex<0.5)
  181.     {
  182. #endif
  183.        glPushMatrix();
  184.        glTranslatef( 1.0, 1.5, 0.0 );
  185.        glRotatef( spin, 1.0, 0.5, 0.0 );
  186.        glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  187.        glCallList( objects_list[0] );
  188.        glPopMatrix();
  189.     
  190.        glPushMatrix();
  191.        glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
  192.        glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  193.        glRotatef( spin, 1.0, 0.5, 0.0 );
  194.        glScalef( 0.5, 0.5, 0.5 );
  195.        glCallList( objects_list[1] );
  196.        glPopMatrix();
  197. #ifndef USE_ZBUFFER
  198.     }
  199.     else
  200.     {    
  201.        glPushMatrix();
  202.        glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
  203.        glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  204.        glRotatef( spin, 1.0, 0.5, 0.0 );
  205.        glScalef( 0.5, 0.5, 0.5 );
  206.        glCallList( objects_list[1] );
  207.        glPopMatrix();
  208.  
  209.        glPushMatrix();
  210.        glTranslatef( 1.0, 1.5, 0.0 );
  211.        glRotatef( spin, 1.0, 0.5, 0.0 );
  212.        glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  213.        glCallList( objects_list[0] );
  214.        glPopMatrix();
  215.     }
  216. #endif
  217. }
  218.  
  219.  
  220.  
  221. static void draw_table( void )
  222. {
  223.    glCallList( table_list );
  224. }
  225.  
  226.  
  227.  
  228. static void draw_scene( void )
  229. {
  230.    GLfloat dist = 20.0;
  231.    GLfloat eyex, eyey, eyez;
  232.  
  233.    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  234.  
  235.  
  236.    eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  237.    eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  238.    eyey = dist * sin(xrot*DEG2RAD);
  239.  
  240.    /* view from top */
  241.    glPushMatrix();
  242.    gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0,  0.0, 1.0, 0.0 );
  243.  
  244.  
  245.    /* draw table into stencil planes */
  246.    glEnable( GL_STENCIL_TEST );
  247. #ifdef USE_ZBUFFER
  248.    glDisable( GL_DEPTH_TEST );
  249. #endif
  250.    glStencilFunc( GL_ALWAYS, 1, 0xffffffff );
  251.    glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );
  252.    glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
  253.    draw_table();
  254.    glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
  255.  
  256. #ifdef USE_ZBUFFER
  257.    glEnable( GL_DEPTH_TEST );
  258. #endif
  259.  
  260.  
  261.    /* render view from below (reflected viewport) */
  262.    /* only draw where stencil==1 */
  263.    if (eyey>0.0) {
  264.       glPushMatrix();
  265.  
  266.       glStencilFunc( GL_EQUAL, 1, 0xffffffff );  /* draw if ==1 */
  267.       glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
  268.       glScalef( 1.0, -1.0, 1.0 );
  269.       draw_objects(eyex, eyey, eyez);
  270.       glPopMatrix();
  271.    }
  272.  
  273.    glDisable( GL_STENCIL_TEST );
  274.  
  275.    glEnable( GL_BLEND );
  276.    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  277.  
  278. #ifdef USE_TEXTURE
  279.    glEnable( GL_TEXTURE_2D );
  280. #endif
  281.    draw_table();
  282.    glDisable( GL_TEXTURE_2D );
  283.    glDisable( GL_BLEND );
  284.  
  285.    /* view from top */
  286.    glPushMatrix();
  287.  
  288.    draw_objects(eyex, eyey, eyez);
  289.  
  290.    glPopMatrix();
  291.  
  292.    glPopMatrix();
  293.  
  294.    tkSwapBuffers();
  295. }
  296.  
  297.  
  298.  
  299. #if 0
  300. void draw_scene(void)
  301. {
  302.    GLfloat dist = 20.0;
  303.    GLfloat eyex, eyey, eyez;
  304.  
  305.    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  306.  
  307.  
  308.    eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  309.    eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  310.    eyey = dist * sin(xrot*DEG2RAD);
  311.  
  312.    /* view from top */
  313.    glPushMatrix();
  314.    gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0,  0.0, 1.0, 0.0 );
  315.  
  316.    draw_table();
  317.  
  318.    glPopMatrix();
  319.  
  320.    tkSwapBuffers();
  321. }
  322. #endif
  323.  
  324.  
  325. GLenum key( int key, GLenum mask )
  326. {
  327.    switch (key) {
  328.       case 27:
  329.          exit(0);
  330.          break;
  331.  
  332.       case TK_UP:
  333.          xrot += 3.0;
  334. #ifndef USE_ZBUFFER
  335.          if ( xrot > 180 )    xrot = 180;
  336. #endif
  337.          break;
  338.       case TK_DOWN:
  339.          xrot -= 3.0;
  340. #ifndef USE_ZBUFFER
  341.          if ( xrot < 0 )    xrot = 0;
  342. #endif
  343.          break;
  344.       case TK_LEFT:
  345.          yrot += 3.0;
  346.          break;
  347.       case TK_RIGHT:
  348.          yrot -= 3.0;
  349.          break;
  350.    }
  351.    return 0;
  352. }
  353.  
  354.  
  355.  
  356. static void idle( void )
  357. {
  358.    spin += 2.0;
  359.    yrot += 3.0;
  360.    draw_scene();
  361. }
  362.  
  363.  
  364.  
  365. int main( int argc, char *argv[] )
  366. {
  367.     tkInitDisplayMode(TK_DOUBLE | TK_RGB 
  368. #ifdef USE_ZBUFFER
  369.         | TK_DEPTH 
  370. #endif
  371.         | TK_STENCIL);
  372.     tkInitPosition( 0, 0, 400, 300 );
  373.     tkInitWindow(argv[0]);
  374.     tkReshapeFunc(reshape);
  375.     tkDisplayFunc(draw_scene);
  376.     tkKeyDownFunc(key);
  377.     tkIdleFunc(idle);
  378.  
  379.     init();
  380.  
  381.     tkExec();
  382.     return 0;
  383. }
  384.